-module(server2).
-export([start/2, rpc/2]).

start(Name, Mod) ->
	io:fwrite("Starting server..."),
	Dict = Mod:init(),
	register(Name, spawn(fun() -> loop(Name, Mod, Dict) end)).
	
rpc(Name, Request) ->
	Name ! {self(), Request},
	receive
		{Name, crash} -> exit(rpc);
		{Name, ok, Response} -> Response
	end.
	
loop(Name, Mod, OldState) ->
	io:fwrite("Old State: ~p~n", [OldState]),
	receive
		{From, Request} ->
			try Mod:handle(Request, OldState) of
				{Response, NewState} ->
					From ! {Name, ok, Response},
					loop(Name, Mod, NewState)
			catch
				_:Why ->
					log_error(Name, Request, Why),
					%% Send the message to cause the client
					From ! {Name, crash},
					%% loop with the original state
					loop(Name, Mod, OldState)
			end;
		Any ->
			Any
	end.
	
log_error(Name, Request, Why) ->
	io:format("Server ~p~n request ~p~n caused exception ~p~n", [Name, Request, Why]).
	
